﻿using System.Collections.Generic;
using System.Linq;
using Coder.Workflow;
using Coder.Workflow.Searcher;
using Coder.Workflow.Stores;
using Fee.Stores;
using Identity;
using Microsoft.EntityFrameworkCore;
using Remotion.Linq.Utilities;
using Text.Helper;

namespace Fee.Orders.AuthProjectWorkflow
{

    public class AuthProjectManager<T> : WorkflowManager<T, AuthProjectOrder>
        where T : FeeDbContext
    {

        private readonly T _context;
        private readonly IWorkProcessStore<T> _workProcessStore;

        public AuthProjectManager(T context, IWorkActivityStore<T> workActivityStore,
            IWorkProcessStore<T> workProcessStore) : base(context,
            workActivityStore)
        {
            _context = context;

            _workProcessStore = workProcessStore;
        }

        public override AuthProjectOrder GetById(int id)
        {
            var result = Context
                .Set<AuthProjectOrder>()
                .Include(f => f.WorkProcess).ThenInclude(f => f.Items)
                .Include(f => f.User)
                .Include(f => f.CostDetails).ThenInclude(f => f.CostDetails)
                .Include(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Station).ThenInclude(f => f.District)
                .Include(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Station).ThenInclude(f => f.OrderDistrict)
                .Include(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Details).ThenInclude(f => f.Project)
                .Include(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Details).ThenInclude(f => f.Contract).ThenInclude(f=>f.Vendor)

                .FirstOrDefault(f => f.Id == id);


            foreach (var item in result.CostDetails)
            {
                item.Cauclate();
            }

            return result;
        }


        protected override IQueryable<WorkActivity> FillQuery(IQueryable<WorkActivity> workActivities)
        {
            return base.FillQuery(workActivities)
                .Include(f => (AuthProjectOrder)f.ProcessInstance).ThenInclude(f => f.CostDetails).ThenInclude(f => f.CostDetails)
                .Include(f => (AuthProjectOrder)f.ProcessInstance).ThenInclude(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Station).ThenInclude(f => f.District)
                .Include(f => (AuthProjectOrder)f.ProcessInstance).ThenInclude(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Station).ThenInclude(f => f.OrderDistrict)
                .Include(f => (AuthProjectOrder)f.ProcessInstance).ThenInclude(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Details).ThenInclude(f => f.Contract).ThenInclude(f => f.Vendor)
                .Include(f => (AuthProjectOrder)f.ProcessInstance).ThenInclude(f => f.CostDetails).ThenInclude(f => f.ConstructionTask).ThenInclude(f => f.Details).ThenInclude(f => f.Project);
        }

        public IEnumerable<WorkActivity> GetMyTask(WorkActivitySearcher searcher, out int total)
        {
            searcher.ProcessType = new[] { "AuthProjectWorkProcess" };

            var query = this.GetMyWork(searcher);

            total = query.Count();

            return query
                .Skip(searcher.GetSkip()).Take(searcher.GetTake()).ToList();
        }

        public OrderResult<AuthProjectOrder> Create(User user)
        {
            var result = new OrderResult<AuthProjectOrder>();
            var wpf = _workProcessStore.Get<AuthProjectWorkProcess>();

            result.Order = wpf.Create(user);

            result.Successed = true;
            return result;
        }

        public override WorkActivity GetWorkActivity(int id, bool includeExtentInfo = false)
        {
            var result = base.GetWorkActivity(id, includeExtentInfo);
            var authProjectOrder = (AuthProjectOrder)result.ProcessInstance;
            foreach (var item in authProjectOrder.CostDetails)
            {
                item.Cauclate();// 计算一次费用。
            }
            return result;

        }
    }
}